package com.btpj.jwt.filter;

import com.btpj.jwt.entity.RespBean;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * Jwt Token验证过滤器
 *
 * @author BTPJ  2020/8/18
 */
public class JwtFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException {
        try {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            String jwtToken = request.getHeader("authorization");
            Claims claims = Jwts.parser().setSigningKey("BTPJ").parseClaimsJws(jwtToken.replace("Bearer", "")).getBody();
            String userName = claims.getSubject();
            List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get("authorities"));
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userName, null, authorities);
            SecurityContextHolder.getContext().setAuthentication(token);
            filterChain.doFilter(servletRequest, servletResponse);
        } catch (Exception e) {
            // e.printStackTrace();
            servletResponse.setContentType("application/json;charset=utf-8");
            PrintWriter out = servletResponse.getWriter();
            RespBean respBean = new RespBean();
            if (e instanceof ExpiredJwtException) {
                respBean.setMsg("用户过期请重新登录");
            } else {
                respBean.setMsg("Token错误");
            }
            out.write(new ObjectMapper().writeValueAsString(respBean));
            out.flush();
            out.close();
        }
    }
}
